<template>
    <div :name="amisName" >Loading...</div>
</template>


<script setup lang="ts">

// 页面切换的时候，会触发该按钮的 click 事件
import {string} from "vue-types";

const AMIS_FORM_ACTIVED_BUT = "u:amisFormActivedBut"
// 外部获取amis内部 form 组件的表单值
const AMIS_GET_FORM_VALUE_FORM_ID = "u:amisGetFormValueFormId"
const AMIS_UNMOUNTED_BUTTON_ID = "u:amisUnmountedButtonId"



import {useTagsViewStore} from "@/store/modules/tagsView";

console.log("AmisFormComponent.vue。。。。")

import {watch, ref, PropType} from "vue"
import {ElMessage, ElMessageBox, ElNotification} from 'element-plus'
import { useI18n } from '../../hooks/web/useI18n'
import request from '@/config/axios/amisAxios'
import copy from 'copy-to-clipboard'
import { generateUUID } from '@/utils'
import * as FormApi from "@/api/bpm/form";
import * as AmisFormContext from "@/components/AmisFormComponent/amisFormContext";
const message = useMessage() // 消息弹窗
const { delView } = useTagsViewStore() // 视图操作


defineOptions({ name: 'AmisFormComponent' })

// window.enableAMISDebug = true;

const props = defineProps({
  formContext: {
    type: Object as PropType<AmisFormContext>,
    required: true
  },
  formData: {
    type: Object ,
    required: false,
    default: ()=>{
      return {};
    }
  }
})


function loadScript(src, callback) {
  const script = document.createElement("script");
  script.setAttribute("type", "text/javascript");
  script.setAttribute("src", src);
  script.onload = () => callback();
  script.onerror = () => callback(new Error(`Failed to load ${src}`));
  document.body.appendChild(script);
}

function loadStyles(styles) {
  for (const path of styles) {
    const style = document.createElement("link");
    style.setAttribute("rel", "stylesheet");
    style.setAttribute("type", "text/css");
    style.setAttribute("href", path);
    document.head.appendChild(style);
  }
}

function loadSDK() {
  return new Promise((resolve, reject) => {
    if (window.amisRequire) {
      resolve();
      return;
    }
    loadStyles([
      "/amis/sdk/sdk.css",
      "/amis/sdk/helper.css",
      "/amis/sdk/iconfont.css",
    ]);
    loadScript("/amis/sdk/sdk.js", (err) => {
      if (err) {
        reject(err);
        return;
      }
      resolve();
    });
  });
}

// window.enableAMISDebug = true

const loading = ref(false)
const unmounted = ref(false)
const amisInstance = ref()
const formJson = ref({})
const amisName = ref("amisName"+ generateUUID())
const route = useRouter() // 路由信息
const { t } = useI18n()

const getAmisJsonByKey = async (amisFormKey) => {
  let formDate = await FormApi.getFormByFormKey(amisFormKey)
  const schema = JSON.parse(formDate.jsonStr)
  console.log("schema",schema)
  return schema ;
}
const getFormById = async (amisFormId) => {
  let formDate = await FormApi.getForm(amisFormId)
  const schema = JSON.parse(formDate.jsonStr)
  console.log("schema",schema)
  return schema ;
}

onMounted(async () => {
  console.log("AmisFormComponent.vue   onMounted...")

  if(!!props.formContext.amisFormKey){
    formJson.value = await getAmisJsonByKey(props.formContext.amisFormKey);
  }else if(!!props.formContext.amisFormId){
    formJson.value = await getFormById(props.formContext.amisFormId);
  }else {
    throw new Error("Amis传入参数错误")
  }

  try {
    loading.value = true;
    await loadSDK();
  } finally {
    loading.value = false;
  }
  if (unmounted.value) {
    return;
  }
  console.log("formJson",formJson.value)

  console.log("route",route)

  // @ts-ignore
  const amis = amisRequire('amis/embed');
  const { normalizeLink } = amisRequire("amis");

  watch(()=> formJson.value, (data)=>{
        onRendering(data)
      },
      {immediate: true,deep: true}
  )

  function onRendering(data:any){
    // let amisScoped = amis.embed('#amisid', data);
    let theme = 'cxd'
    amisInstance.value = amis.embed(
        "[name='"+amisName.value+"']",
        data,
        {
          updateLocation: (to, replace) => {},
          // 赋予 amis 顶层数据域的值
          data: {
            ...props.formData
          },
          // context 数据，无论哪层都可以使用到这个里面的数据
          context: {
            ...props.formContext
          }
        },
        {
          // 下面三个接口必须实现
          fetcher: ({
                      url, // 接口地址
                      method, // 请求方法 get、post、put、delete
                      data, // 请求数据
                      responseType,
                      config, // 其他配置
                      headers ,// 请求头
                      updateLocation
                    }) => {
            config = config || {};
            config.withCredentials = true;

            // 设置接口地址
            // config.baseURL = import.meta.env.VITE_APP_BASE_API;

            responseType && (config.responseType = responseType);

            // if (config.cancelExecutor) {
            //     config.cancelToken = new (axios).CancelToken(
            //         config.cancelExecutor
            //     );
            // }

            config.headers = headers || {};

            // 设置token
            // const isToken = (config.headers || {}).isToken === false
            // if (getToken() && !isToken) {
            //     config.headers['token'] = getToken()
            // }

            // responseType: "blob"
            console.log(url, data, config,'url, data, config')
            if(config["responseType"] == "blob"){
              method = "download" ;
            }

            if (method !== 'post' && method !== 'put' && method !== 'patch') {
              if (data) {
                config.params = data;
              }

              // return (axios )[method](url, config);
              return (request )[method]({url, config});
            } else if (data && data instanceof FormData) {
              config.headers = config.headers || {};
              config.headers['Content-Type'] = 'multipart/form-data';
              method = "upload" ;
            } else if (data && typeof data !== 'string' && !(data instanceof Blob) && !(data instanceof ArrayBuffer)) {
              data = JSON.stringify(data);
              config.headers = config.headers || {};
              config.headers['Content-Type'] = 'application/json';
            }

            // return (axios )[method](url, data, config);
            return (request )[method]({url, data, config});
          },
          // isCancel: (value) => (axios ).isCancel(value),
          copy: content => {
            copy(content);
            ElMessage.success('内容已复制到粘贴板');
          },
          jumpTo: (to, action) => {
            console.log('jumpTo: (to, action)',to, action)
            if (to === "goBack") {
                // 关闭当前 Tab
                delView(unref(route.currentRoute))
                // 退回上个路由
                return route.go(-1);
            }

            // 路由模式改编为：createWebHashHistory 所以注释掉
            // to = normalizeLink(to, location);

            if (action?.actionType === "url") {
              action.blank === false ? route.push(to) : window.open(to);
              return;
            }

            // 主要是支持 nav 中的跳转
            if (action && to && action.target) {
              window.open(to, action.target);
              return;
            }

            if (/^https?:\/\//.test(to)) {
              window.location.replace(to);
            } else {
                route.push(to);
            }
          },
          updateLocation: (location, replace) => {
            console.log('updateLocation: (location, replace)',location, replace)
            if (location === "goBack") {
              return route.go(-1);
            }

            // 此处不能更新路由，否则tab页面会不断刷新
            // location = normalizeLink(location);
            // replace ? route.replace(location) : route.replace(location);
          },
          // 用来配置弹窗等组件的挂载位置
          // todo amis对象的作用域是全局的，所以这边不能这么写
          // getModalContainer: () => {
          //   console.log("getModalContainer....")
          //   return document.getElementsByName(amisName.value)[0]
          // },
          // 用来实现通知
          notify: (type, msg) => {
            console.log("notify....",type, msg)
            if(type == "error"){
              message.notifyError(msg)
            }
            else if(type == "info"){
              message.notify(msg)
            }
            else if(type == "success"){
              message.notifySuccess(msg)
            }
            else if(type == "warning"){
              message.notifyWarning(msg)
            }
          },
          // 用来实现提示
          alert: content => {
            console.log("alert....",content)
            return ElMessageBox.alert(content, t('common.confirmTitle'))
          },
          // 用来实现确认框。
          confirm: content => {
            console.log("confirm....",content)
            return message.confirm(content)
          },
          // 在amis里面广播调用外部
          // https://aisuda.bce.baidu.com/amis/zh-CN/docs/extend/ui-library#%E7%9B%91%E5%90%AC%E5%B9%BF%E6%92%AD%E4%BA%8B%E4%BB%B6
          onBroadcast: (type, rawEvent, data) => {
              console.log('onBroadcast...',type, rawEvent, data);
          },
          // Toast提示弹出位置，默认为'top-center'
          toastPosition: 'center',
          theme,
          // 关闭 移动端原生 UI，防止WPS中以移动端显示
          useMobileUI: false
        }
    )
  }
})
onUnmounted(async () => {
  console.log("AmisFormComponent.vue   onUnmounted...")
  unmounted.value = true;
  amisInstance.value.unmount();
})
onActivated(()=>{
    console.log("AmisFormComponent...onActivated...")
  // 页面被激活，需要调用内部
  amisFormActived();
})

const amisFormActived = function (){
  amisInstance.value?.getComponentById(AMIS_FORM_ACTIVED_BUT)?.doAction({
    actionType: "click",
  })
}
const getFormDate = function (){
  console.log("getFormDate...")
  return amisInstance.value?.getComponentById(AMIS_GET_FORM_VALUE_FORM_ID)?.getData() ;
}
const onAmisUnmounted = function (){
  // 调用挂载的事件
  console.log("onAmisUnmounted...")
  amisInstance.value?.doAction({
    "actionType": "click",
    "componentId": AMIS_UNMOUNTED_BUTTON_ID
  })

}

// 暴露方法，提供给父组件
defineExpose({getFormDate,onAmisUnmounted})


</script>

